﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;
using DevExpress.XtraBars.Ribbon;
using DevExpress.XtraTabbedMdi;
using Loki.Engine;
using Loki.Utils;

namespace Loki.UI.Win
{
    public class MDIContainerRibbonViewBase : RibbonViewBase
    {
        protected XtraTabbedMdiManager MDI_Manager;
        protected RibbonStatusBar RBN_StatusBar;
        private IContainer components;

        public MDIContainerRibbonViewBase()
            : base()
        {
            InitializeComponent();
            BindNameOnVMState = false;
            MDI_Manager.PageRemoved += MDI_Manager_PageRemoved;
            MDI_Manager.SelectedPageChanged += MDI_Manager_SelectedPageChanged;
            BindingChanged += InitializeBindings;
            BindingChanging += ClearViewModelEvents;
        }

        void MDI_Manager_SelectedPageChanged(object sender, EventArgs e)
        {
            List<XtraMdiTabPage> l_pages = MDI_Manager.Pages.Cast<XtraMdiTabPage>().ToList();
            foreach (var item in l_pages)
            {
                RibbonViewBase L_Base = item.MdiChild as RibbonViewBase;
                if (L_Base != null && L_Base.ViewModel != null)
                {
                    if (item == MDI_Manager.SelectedPage)
                    {
                        if (!L_Base.ViewModel.IsActive)
                            L_Base.ViewModel.Activate.Execute(null);
                    }
                    else if (L_Base.ViewModel.IsActive)
                        L_Base.ViewModel.Desactivate.Execute(null);
                }
            }
        }

        protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, Keys keyData)
        {
            if (keyData == (Keys.Tab | Keys.Control))
            {
                if (MDI_Manager.Pages.Count > 0)
                {
                    XtraMdiTabPage L_LastPage = MDI_Manager.Pages[MDI_Manager.Pages.Count - 1];
                    if (MDI_Manager.SelectedPage != L_LastPage)
                    {
                        MDI_Manager.SelectedPage = MDI_Manager.Pages[MDI_Manager.Pages.IndexOf(MDI_Manager.SelectedPage) + 1];
                        return true;
                    }
                }
                return false;
            }
            else if (keyData == (Keys.Control | Keys.Tab | Keys.Shift))
            {
                if (MDI_Manager.Pages.Count > 0)
                {
                    XtraMdiTabPage L_FirstPage = MDI_Manager.Pages[0];
                    if (MDI_Manager.SelectedPage != L_FirstPage)
                    {
                        MDI_Manager.SelectedPage = MDI_Manager.Pages[MDI_Manager.Pages.IndexOf(MDI_Manager.SelectedPage) - 1];
                        return true;
                    }
                }
                return false;
            }
            else
                return base.ProcessCmdKey(ref msg, keyData);
        }

        void MDI_Manager_PageRemoved(object sender, DevExpress.XtraTabbedMdi.MdiTabPageEventArgs e)
        {
            RibbonViewBase L_View = e.Page.MdiChild as RibbonViewBase;
            if (L_View != null && L_View.ViewModel != null)
                L_View.ViewModel.Close.Execute(L_View.ViewModel);
        }

        private void InitializeBindings(object sender, EventArgs e)
        {
            CreateItems(ViewModel.SubModels);
            this.WatchCollectionChange(ViewModel.SubModels, v => v.ViewModels_CollectionChanged);
        }

        protected void ClearViewModelEvents(object sender, EventArgs e)
        {
            if (ViewModel != null)
                ViewModel.SubModels.CollectionChanged -= ViewModels_CollectionChanged;
        }

        private void CreateItems(IEnumerable P_Models)
        {
            foreach (IViewModel L_Model in P_Models)
            {
                LokiServices.Event.RegisterPropertyChanged(L_Model, x => x.IsActive, this, (c, s, a) => c.ViewModel_ActivatedChanged(s, a));
                RibbonViewBase L_View = ContextHelper.GetView<RibbonViewBase>(L_Model);
                if (L_View != null)
                {
                    L_View.MdiParent = this;
                    L_View.Show();
                }
            }
        }

        private void ViewModels_CollectionChanged(object P_Sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems != null)
            {
                CreateItems(e.NewItems);
            }
            if (e.OldItems != null)
            {
                foreach (IViewModel L_Model in e.OldItems)
                {
                    LokiServices.Event.UnregisterPropertyChanged(L_Model, x => x.IsActive, this);
                }
            }
        }

        private void ViewModel_ActivatedChanged(object sender, PropertyChangedEventArgs e)
        {
            List<XtraMdiTabPage> l_pages = MDI_Manager.Pages.Cast<XtraMdiTabPage>().Reverse().ToList();
            foreach (var item in l_pages)
            {
                RibbonViewBase L_Base = item.MdiChild as RibbonViewBase;
                if (L_Base != null && L_Base.ViewModel == sender && L_Base.ViewModel.IsActive)
                    if (MDI_Manager.SelectedPage != item)
                    {
                        MDI_Manager.SelectedPage = item;
                    }
            }
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            List<XtraMdiTabPage> l_pages = MDI_Manager.Pages.Cast<XtraMdiTabPage>().Reverse().ToList();
            foreach (var item in l_pages)
            {
                RibbonViewBase L_Base = item.MdiChild as RibbonViewBase;
                if (L_Base != null)
                {
                    if (L_Base.ViewModel.IsDirty)
                    {
                        if (MessageBoxes.Confirm(Messages.UIMessages.CONFIRM_EXTERNAL_CLOSE, L_Base.Text))
                        {
                            if (MDI_Manager.SelectedPage == item && MDI_Manager.Pages.Count > 1)
                            {
                                MDI_Manager.SelectedPage = MDI_Manager.Pages[MDI_Manager.Pages.IndexOf(item) - 1];
                            }
                            L_Base.ViewModel.AcceptChanges();
                            L_Base.Close();
                        }
                        else
                        {
                            MDI_Manager.SelectedPage = item;
                            e.Cancel = true;
                            return;
                        }
                    }
                    else
                        L_Base.Close();
                }
            }
            base.OnClosing(e);
        }

        public new IContainerViewModel ViewModel
        {
            get { return (IContainerViewModel)base.ViewModel; }
            set { base.ViewModel = value; }
        }

        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.MDI_Manager = new DevExpress.XtraTabbedMdi.XtraTabbedMdiManager(this.components);
            this.RBN_StatusBar = new DevExpress.XtraBars.Ribbon.RibbonStatusBar();
            ((System.ComponentModel.ISupportInitialize)(this.RBN_MainRibbon)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.MDI_Manager)).BeginInit();
            this.SuspendLayout();
            // 
            // ribbonControl1
            // 
            this.RBN_MainRibbon.ExpandCollapseItem.Id = 0;
            this.RBN_MainRibbon.ExpandCollapseItem.Name = "";
            this.RBN_MainRibbon.Size = new System.Drawing.Size(943, 74);
            this.RBN_MainRibbon.StatusBar = this.RBN_StatusBar;
            // 
            // MDI_Manager
            // 
            this.MDI_Manager.ClosePageButtonShowMode = DevExpress.XtraTab.ClosePageButtonShowMode.InAllTabPageHeaders;
            this.MDI_Manager.MdiParent = this;
            // 
            // ribbonStatusBar1
            // 
            this.RBN_StatusBar.Location = new System.Drawing.Point(0, 494);
            this.RBN_StatusBar.Name = "ribbonStatusBar1";
            this.RBN_StatusBar.Ribbon = this.RBN_MainRibbon;
            this.RBN_StatusBar.Size = new System.Drawing.Size(943, 39);
            // 
            // MDIContainerRibbonViewBase
            // 
            this.AllowDisplayRibbon = true;
            this.AllowMdiBar = true;
            this.ClientSize = new System.Drawing.Size(943, 533);
            this.Controls.Add(this.RBN_StatusBar);
            this.IsMdiContainer = true;
            this.Name = "MDIContainerRibbonViewBase";
            this.StatusBar = this.RBN_StatusBar;
            this.Controls.SetChildIndex(this.RBN_StatusBar, 0);
            this.Controls.SetChildIndex(this.RBN_MainRibbon, 0);
            ((System.ComponentModel.ISupportInitialize)(this.RBN_MainRibbon)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.MDI_Manager)).EndInit();
            this.ResumeLayout(false);

        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose(disposing);
        }
    }
}
